#!/usr/bin/envpython
# -*-coding:UTF-8-*-
'''
@File    :   slash_strip_handle.py
@Contact :   308711822@qq.com
@License :   (C) Copyright 2021-2225, Personal exclusive right.

@Modify Time      @Author    @Version    @Desciption
------------      -------    --------    -----------
2023/2/1 10:33   小钟同学      1.0         None
'''

import functools
from datetime import time

from starlette.middleware.base import BaseHTTPMiddleware
from starlette.requests import Request
from starlette.types import ASGIApp, Message, Receive, Scope, Send


class SlashStripHandleMiddleware:
    '''
    尾部斜杠引发重定向问题处理中间件，！！
    ！需要注意，此中间件仅用于 存在因为URL后尾斜杠引发重定向问题才会使用到，！如果不存在则不要使用！
    如果自定义中间件，注册的位置可以放在
         def _register_middlewares(self, core_app: FastAPI) -> None:
        pass
        core_app.add_middleware(
            CORSMiddleware,
            allow_origins=["*"],
            allow_credentials=True,
            allow_methods=["*"],
            allow_headers=["*"],
        )
        # 测试验证可以读取响应报文和读取请求报文信息的中间件
        from afast_core.core_middleware.request_response import RequestResponseMiddleware
        core_app.add_middleware(RequestResponseMiddleware)
        core_app.add_middleware(SlashStripHandleMiddleware)
    '''

    def __init__(self, app: ASGIApp) -> None:
        self.app = app

    async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
        if scope["type"] != "http":
            await self.app(scope, receive, send)
            return
        # 解析当前的请求体
        request = Request(scope, receive=receive)
        # 处理URL请求中尾部的斜杠问题，避免重定向问题
        if request.url.path != "/" and request.url.path[-1] == "/":
            replace_path = request.url.path[:-1]
            request._url = request.url.replace(path=replace_path)
            request.scope["path"] = replace_path
            request.scope["raw_path"] = replace_path.encode()

        # 自动传参，如果对于send有需要重写的需求，则需要进行重写
        send = functools.partial(self.send, send=send, request=request)
        # 自定义回调函数，可以自己进行重写实现具体的业务逻辑
        await self.app(request.scope, receive, send)

    async def send(self, message: Message, send: Send, request: Request) -> None:
        """重写send方法【不重写则默认使用原来的】"""
        return await send(message)


class SlashStripHandleMiddleware2(BaseHTTPMiddleware):
    '''
    如果基于BaseHTTPMiddleware，则对应的注册位置需要放在最前面进行处理，如下：
     def _register_global_request(self, core_app: FastAPI) -> None:
        # 注册应用全局请求的request
        pass
        GlobalRequestPluginClient(core_app=core_app)
        logger.info("GlobalRequestPluginClient插件安装成功")
        core_app.add_middleware(SlashStripHandleMiddleware2)
    '''

    def __init__(self, app: ASGIApp):
        super().__init__(app)

    async def dispatch(self, request, call_next):
        if request.url.path != "/" and request.url.path[-1] == "/":
            pass
            replace_path = request.url.path[:-1]
            request._url = request.url.replace(path=replace_path)
            request.scope["path"] = replace_path
            request.scope["raw_path"] = replace_path.encode()
        return await call_next(request)
